package com.zx.flow.core.execute.eventhandler;

import com.zx.flow.api.config.FlowConfig;
import com.zx.flow.api.config.FlowConfigNode;
import com.zx.flow.api.dict.FlowDict.Event;
import com.zx.flow.api.dict.FlowDict.Status;
import com.zx.flow.api.execute.model.FlowContext;
import com.zx.flow.api.execute.model.FlowNode;
import com.zx.flow.api.execute.request.FlowParamAction;
import com.zx.flow.api.execute.request.FlowParamEnd;
import com.zx.flow.api.execute.request.FlowParamNodeEntry;
import com.zx.flow.api.execute.response.FlowResult;
import com.zx.flow.api.util.FlowDataUtil;
import com.zx.flow.api.util.OperatorsUtil;
import com.zx.flow.core.execute.EventHandler;
import java.util.Collections;
import java.util.Date;
import java.util.Objects;
import org.springframework.util.StringUtils;

/**
 * 事件处理器【流程->结束】
 */
public class EventFlowEndHandler extends EventHandler<FlowParamEnd> {

    @Override
    public boolean in(FlowContext flow, FlowParamEnd param) {
        return flow != null && !Objects.equals(flow.getStatus(), Status.flowEnd);
    }

    @Override
    public FlowResult on(FlowContext flow, FlowParamEnd param) {
        FlowConfig config = this.getFlowConfig(flow.getFlowConfigCode(), flow.getFlowConfigId());
        FlowConfigNode endNodeConfig = config.getEndNode();
        // node entry 开始节点
        flow = this.execute(new FlowParamNodeEntry(flow.getId(), endNodeConfig.getCode(), Collections.emptyList()))
                .getFlowContext();
        // 获得当前节点
        FlowNode endNode = FlowDataUtil.getCurrent(flow);
        // node action【系统自动通过】
        flow = this.execute(new FlowParamAction(endNode.getFlowId(), endNode.getId(), Event.nodeApproved.getCode()
                , "流程结束", OperatorsUtil.getSystemCode())).getFlowContext();

        // 保存流程数据
        flow.setEndDateTime(new Date());
        flow.setStatus(Status.flowEnd);
        this.saveFlow(flow);

        // 触发监听
        this.listener(endNode, Event.flowEnd);

        // 通知父流程
        if (!StringUtils.isEmpty(flow.getParentFlowId())) {
            // 父流程的node提交
            flow = this.execute(new FlowParamAction(flow.getParentFlowId(), flow.getParentNodeId(),
                    Event.nodeApproved.getCode(), "[子流程]流程结束", OperatorsUtil.getSystemCode())).getFlowContext();
        }
        return FlowResult.ok(flow);
    }
}
